package com.lzx;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;

public class ABADemo {
    static AtomicReference<Integer> atomicReference = new AtomicReference<Integer>(100);
    static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100,1);
    public static void main(String[] args) {
        System.out.println("==================以下产生ABA问题==================");
        new Thread(() -> {
            atomicReference.compareAndSet(100, 101);
            atomicReference.compareAndSet(101, 100);
        }, "t1").start();

        new Thread(()->{
            try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedException e){ e.printStackTrace();}
            System.out.println(atomicReference.compareAndSet(100,2020)+"\t " +atomicReference.get());
        },"t2").start();

        try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException e){ e.printStackTrace();}
        System.out.println("==================以下解决ABA问题==================");

        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();
            System.out.println(Thread.currentThread().getName()+"\t 第1次版本: "+stamp);
             try{TimeUnit.SECONDS.sleep(1); }catch(InterruptedException e){ e.printStackTrace();}
            atomicStampedReference.compareAndSet(100, 101, atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);
            System.out.println(Thread.currentThread().getName()+"\t 第2次版本: "+atomicStampedReference.getStamp());
            atomicStampedReference.compareAndSet(101, 100, atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);
            System.out.println(Thread.currentThread().getName()+"\t 第3次版本: "+atomicStampedReference.getStamp());
        },"t3").start();

        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();
            System.out.println(Thread.currentThread().getName()+"\t 第1次版本: "+stamp);
            try{TimeUnit.SECONDS.sleep(3);}catch(InterruptedException e){ e.printStackTrace();}
            boolean flag = atomicStampedReference.compareAndSet(100, 2020, stamp, stamp+ 1);
            System.out.println(Thread.currentThread().getName()+"\t 第4次版本："+ atomicStampedReference.getStamp());
            System.out.println("当前实际值是：" + atomicStampedReference.getReference()+", 是否成功 ："+flag);
        },"t4").start();





    }

}
